package com.example.plantuml.demo.config;

import com.example.plantuml.aspect.BaseRequestTraceAspect;
import com.example.plantuml.model.RequestTrace;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * 请求跟踪AOP切面，用于无侵入式地记录方法调用链
 */
@Aspect
@Component
@Slf4j
public class RequestTraceAspectAspect extends BaseRequestTraceAspect {

    /**
     * 定义Controller层的切入点
     */
    @Pointcut("execution(* com.example.plantuml.demo.controller..*(..))")
    public void controllerPointcut() {
    }

//    @Pointcut("execution(* com.example.plantuml.demo..*(..)) ")
//    public void compoentPointcut() {
//    }

    /**
     * 定义Service层的切入点
     */
    @Pointcut("execution(* com.example.plantuml.demo.service..*(..)) && !execution(* com.example.plantuml.tools.CallChainManager.*(..)) && !execution(* com.example.plantuml.tools.PlantUmlGenerator.*(..))")
    public void servicePointcut() {
    }


    /**
     * 定义Repository层的切入点
     */

    @Pointcut("execution(* com.example.plantuml.demo.repository..*(..))")
    public void repositoryPointcut() {
    }

    /**
     * 环绕通知，用于跟踪Controller方法调用
     */
    @Around("controllerPointcut()")
    public Object aroundController(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取当前请求
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            return joinPoint.proceed();
        }

        HttpServletRequest request = attributes.getRequest();

        // 开始请求跟踪
//        RequestTrace requestTrace = new RequestTrace(request);
//        callChainManager.startRequestTrace(requestTrace);
//
//        log.info("开始跟踪请求: {} {}, Trace ID: {}", request.getMethod(), request.getRequestURI(), requestTrace.getTraceId());

        try {
            return around(joinPoint, request);
        } finally {
            // 结束请求跟踪
            RequestTrace completedTrace = callChainManager.endRequestTrace();
            log.info("请求跟踪结束: {} {}, 总耗时: {}ms, Trace ID: {}",
                    completedTrace.getHttpMethod(),
                    completedTrace.getRequestUrl(),
                    completedTrace.getTotalDuration(),
                    completedTrace.getTraceId());
        }
    }

    /**
     * 环绕通知，用于跟踪Service方法调用
     */
//    @Around("compoentPointcut()")
//    public Object aroundComponent(ProceedingJoinPoint joinPoint) throws Throwable {
//        // 记录Service方法调用
//        return around(joinPoint, null);
//    }

    /**
     * 环绕通知，用于跟踪Service方法调用
     */
    @Around("servicePointcut()")
    public Object aroundService(ProceedingJoinPoint joinPoint) throws Throwable {
        // 记录Service方法调用
        return around(joinPoint, null);
    }

    /**
     * 环绕通知，用于跟踪Repository方法调用
     */
    @Around("repositoryPointcut()")
    public Object aroundRepository(ProceedingJoinPoint joinPoint) throws Throwable {
        // 记录Repository方法调用
        return around(joinPoint, null);
    }
}
